﻿using System;
using UnityEngine;

// Token: 0x02000160 RID: 352
[DisallowMultipleComponent]
[AddComponentMenu("RVP/C#/Drivetrain/Wheel", 1)]
[RequireComponent(typeof(DriveForce))]
[ExecuteInEditMode]
public class Wheel : MonoBehaviour
{
	// Token: 0x0600066D RID: 1645 RVA: 0x0003621C File Offset: 0x0003441C
	private void Start()
	{
		this.tr = base.transform;
		this.rb = (Rigidbody)F.GetTopmostParentComponent<Rigidbody>(this.tr);
		this.vp = (VehicleParent)F.GetTopmostParentComponent<VehicleParent>(this.tr);
		this.suspensionParent = this.tr.parent.GetComponent<Suspension>();
		this.travelDist = this.suspensionParent.targetCompression;
		this.canDetach = (this.detachForce < float.PositiveInfinity && Application.isPlaying);
		this.initialTirePressure = this.tirePressure;
		if (this.tr.childCount > 0)
		{
			this.rim = this.tr.GetChild(0);
			if (this.rimGlow > 0f && Application.isPlaying)
			{
				this.rimMat = new Material(this.rim.GetComponent<MeshRenderer>().sharedMaterial);
				this.rimMat.EnableKeyword("_EMISSION");
				this.rim.GetComponent<MeshRenderer>().material = this.rimMat;
			}
			if (this.canDetach)
			{
				this.detachedWheel = new GameObject(this.vp.transform.name + "'s Detached Wheel");
				this.detachedWheel.layer = LayerMask.NameToLayer("Detachable Part");
				this.detachFilter = this.detachedWheel.AddComponent<MeshFilter>();
				this.detachFilter.sharedMesh = this.rim.GetComponent<MeshFilter>().sharedMesh;
				MeshRenderer meshRenderer = this.detachedWheel.AddComponent<MeshRenderer>();
				meshRenderer.sharedMaterial = this.rim.GetComponent<MeshRenderer>().sharedMaterial;
				this.detachedCol = this.detachedWheel.AddComponent<MeshCollider>();
				this.detachedCol.convex = true;
				this.detachedBody = this.detachedWheel.AddComponent<Rigidbody>();
				this.detachedBody.mass = this.mass;
			}
			if (this.rim.childCount > 0)
			{
				this.tire = this.rim.GetChild(0);
				if (this.deformAmount > 0f && Application.isPlaying)
				{
					this.tireMat = new Material(this.tire.GetComponent<MeshRenderer>().sharedMaterial);
					this.tire.GetComponent<MeshRenderer>().material = this.tireMat;
				}
				if (this.canDetach)
				{
					this.detachedTire = new GameObject("Detached Tire");
					this.detachedTire.transform.parent = this.detachedWheel.transform;
					this.detachedTire.transform.localPosition = Vector3.zero;
					this.detachedTire.transform.localRotation = Quaternion.identity;
					this.detachTireFilter = this.detachedTire.AddComponent<MeshFilter>();
					this.detachTireFilter.sharedMesh = this.tire.GetComponent<MeshFilter>().sharedMesh;
					MeshRenderer meshRenderer2 = this.detachedTire.AddComponent<MeshRenderer>();
					meshRenderer2.sharedMaterial = ((!this.tireMat) ? this.tire.GetComponent<MeshRenderer>().sharedMaterial : this.tireMat);
				}
			}
			if (Application.isPlaying)
			{
				if (this.generateHardCollider)
				{
					GameObject gameObject = new GameObject("Rim Collider");
					gameObject.layer = GlobalControl.ignoreWheelCastLayer;
					this.sphereColTr = gameObject.transform;
					this.sphereCol = gameObject.AddComponent<SphereCollider>();
					this.sphereColTr.parent = this.tr;
					this.sphereColTr.localPosition = Vector3.zero;
					this.sphereColTr.localRotation = Quaternion.identity;
					this.sphereCol.radius = Mathf.Min(this.rimWidth * 0.5f, this.rimRadius * 0.5f);
					this.sphereCol.material = GlobalControl.frictionlessMatStatic;
				}
				if (this.canDetach)
				{
					this.detachedWheel.SetActive(false);
				}
			}
		}
		this.targetDrive = base.GetComponent<DriveForce>();
		this.currentRPM = 0f;
	}

	// Token: 0x0600066E RID: 1646 RVA: 0x00036614 File Offset: 0x00034814
	private void FixedUpdate()
	{
		this.upDir = this.tr.up;
		this.actualRadius = ((!this.popped) ? Mathf.Lerp(this.rimRadius, this.tireRadius, this.tirePressure) : this.rimRadius);
		this.circumference = 3.1415927f * this.actualRadius * 2f;
		this.localVel = this.rb.GetPointVelocity(this.forceApplicationPoint);
		this.actualEbrake = ((!this.suspensionParent.ebrakeEnabled) ? 0f : this.suspensionParent.ebrakeForce);
		this.actualTargetRPM = this.targetDrive.rpm * (float)((!this.suspensionParent.driveInverted) ? 1 : -1);
		this.actualTorque = ((!this.suspensionParent.driveEnabled) ? 0f : Mathf.Lerp(this.targetDrive.torque, Mathf.Abs(this.vp.accelInput), this.vp.burnout));
		if (this.getContact)
		{
			this.GetWheelContact();
		}
		else if (this.grounded)
		{
			this.contactPoint.point += this.localVel * Time.fixedDeltaTime;
		}
		this.airTime = ((!this.grounded) ? (this.airTime + Time.fixedDeltaTime) : 0f);
		this.forceApplicationPoint = ((!this.applyForceAtGroundContact) ? this.tr.position : this.contactPoint.point);
		if (this.connected)
		{
			this.GetRawRPM();
			this.ApplyDrive();
		}
		else
		{
			this.rawRPM = 0f;
			this.currentRPM = 0f;
			this.targetDrive.feedbackRPM = 0f;
		}
		this.travelDist = ((this.suspensionParent.compression >= this.travelDist && !this.grounded) ? Mathf.Lerp(this.travelDist, this.suspensionParent.compression, this.suspensionParent.extendSpeed * Time.fixedDeltaTime) : this.suspensionParent.compression);
		this.PositionWheel();
		if (this.connected)
		{
			if (this.generateHardCollider)
			{
				this.setRimWidth = this.rimWidth;
				this.setRimRadius = this.rimRadius;
				this.setTireWidth = this.tireWidth;
				this.setTireRadius = this.tireRadius;
				this.setTirePressure = this.tirePressure;
				if (this.rimWidthPrev != this.setRimWidth || this.rimRadiusPrev != this.setRimRadius)
				{
					this.sphereCol.radius = Mathf.Min(this.rimWidth * 0.5f, this.rimRadius * 0.5f);
					this.updatedSize = true;
				}
				else if (this.tireWidthPrev != this.setTireWidth || this.tireRadiusPrev != this.setTireRadius || this.tirePressurePrev != this.setTirePressure)
				{
					this.updatedSize = true;
				}
				else
				{
					this.updatedSize = false;
				}
				this.rimWidthPrev = this.setRimWidth;
				this.rimRadiusPrev = this.setRimRadius;
				this.tireWidthPrev = this.setTireWidth;
				this.tireRadiusPrev = this.setTireRadius;
				this.tirePressurePrev = this.setTirePressure;
			}
			this.GetSlip();
			this.ApplyFriction();
			if (this.vp.burnout > 0f && this.targetDrive.rpm != 0f && this.actualEbrake * this.vp.ebrakeInput == 0f && this.connected && this.grounded)
			{
				this.rb.AddForceAtPosition(this.suspensionParent.forwardDir * -this.suspensionParent.flippedSideFactor * (this.vp.steerInput * this.vp.burnoutSpin * this.currentRPM * Mathf.Min(0.1f, this.targetDrive.torque) * 0.001f) * this.vp.burnout * ((!this.popped) ? 1f : 0.5f) * this.contactPoint.surfaceFriction, this.suspensionParent.tr.position, ForceMode.Acceleration);
			}
			this.setPopped = this.popped;
			if (this.poppedPrev != this.setPopped)
			{
				if (this.tire)
				{
					this.tire.gameObject.SetActive(!this.popped);
				}
				this.updatedPopped = true;
			}
			else
			{
				this.updatedPopped = false;
			}
			this.poppedPrev = this.setPopped;
			if (this.airLeakTime >= 0f)
			{
				this.tirePressure = Mathf.Clamp01(this.tirePressure - Time.fixedDeltaTime * 0.5f);
				if (this.grounded)
				{
					this.airLeakTime += Mathf.Max(Mathf.Abs(this.currentRPM) * 0.001f, this.localVel.magnitude * 0.1f) * Time.timeScale * TimeMaster.inverseFixedTimeFactor;
					if (this.airLeakTime > 1000f && this.tirePressure == 0f)
					{
						this.popped = true;
						this.airLeakTime = -1f;
						if (this.impactSnd && this.tirePopClip)
						{
							this.impactSnd.PlayOneShot(this.tirePopClip);
							this.impactSnd.pitch = 1f;
						}
					}
				}
			}
		}
	}

	// Token: 0x0600066F RID: 1647 RVA: 0x00036C0C File Offset: 0x00034E0C
	private void Update()
	{
		this.RotateWheel();
		if (!Application.isPlaying)
		{
			this.PositionWheel();
		}
		else
		{
			if (this.deformAmount > 0f && this.tireMat && this.connected && this.tireMat.HasProperty("_DeformNormal"))
			{
				Vector3 vector = (!this.grounded) ? Vector3.zero : (this.contactPoint.normal * Mathf.Max(-this.suspensionParent.penetration * (1f - this.suspensionParent.compression) * 10f, 1f - this.tirePressure) * this.deformAmount);
				this.tireMat.SetVector("_DeformNormal", new Vector4(vector.x, vector.y, vector.z, 0f));
			}
			if (this.rimMat && this.rimMat.HasProperty("_EmissionColor"))
			{
				float num = (!this.connected || !GroundSurfaceMaster.surfaceTypesStatic[this.contactPoint.surfaceType].leaveSparks) ? 0f : Mathf.Abs(F.MaxAbs(new float[]
				{
					this.forwardSlip,
					this.sidewaysSlip
				}));
				this.glowAmount = ((!this.popped) ? 0f : Mathf.Lerp(this.glowAmount, num, ((num <= this.glowAmount) ? 0.2f : 2f) * Time.deltaTime));
				this.glowColor = new Color(this.glowAmount, this.glowAmount * 0.5f, 0f);
				this.rimMat.SetColor("_EmissionColor", (!this.popped) ? Color.black : Color.Lerp(Color.black, this.glowColor, this.glowAmount * this.rimGlow));
			}
		}
	}

	// Token: 0x06000670 RID: 1648 RVA: 0x00036E30 File Offset: 0x00035030
	private void GetWheelContact()
	{
		float maxDistance = Mathf.Max(this.suspensionParent.suspensionDistance * Mathf.Max(0.001f, this.suspensionParent.targetCompression) + this.actualRadius, 0.001f);
		RaycastHit[] array = Physics.RaycastAll(this.suspensionParent.maxCompressPoint, this.suspensionParent.springDirection, maxDistance, GlobalControl.wheelCastMaskStatic);
		int num = 0;
		bool flag = false;
		float num2 = float.PositiveInfinity;
		if (this.connected)
		{
			for (int i = 0; i < array.Length; i++)
			{
				if (!array[i].transform.IsChildOf(this.vp.tr) && array[i].distance < num2)
				{
					num = i;
					num2 = array[i].distance;
					flag = true;
				}
			}
		}
		else
		{
			flag = false;
		}
		if (flag)
		{
			RaycastHit raycastHit = array[num];
			if (!this.grounded && this.impactSnd && ((this.tireHitClips.Length > 0 && !this.popped) || (this.rimHitClip && this.popped)))
			{
				this.impactSnd.PlayOneShot((!this.popped) ? this.tireHitClips[Mathf.RoundToInt((float)UnityEngine.Random.Range(0, this.tireHitClips.Length - 1))] : this.rimHitClip, Mathf.Clamp01(this.airTime * this.airTime));
				this.impactSnd.pitch = Mathf.Clamp(this.airTime * 0.2f + 0.8f, 0.8f, 1f);
			}
			this.grounded = true;
			this.contactPoint.distance = raycastHit.distance - this.actualRadius;
			this.contactPoint.point = raycastHit.point + this.localVel * Time.fixedDeltaTime;
			this.contactPoint.grounded = true;
			this.contactPoint.normal = raycastHit.normal;
			this.contactPoint.relativeVelocity = this.tr.InverseTransformDirection(this.localVel);
			this.contactPoint.col = raycastHit.collider;
			if (raycastHit.collider.attachedRigidbody)
			{
				this.contactVelocity = raycastHit.collider.attachedRigidbody.GetPointVelocity(this.contactPoint.point);
				this.contactPoint.relativeVelocity -= this.tr.InverseTransformDirection(this.contactVelocity);
			}
			else
			{
				this.contactVelocity = Vector3.zero;
			}
			GroundSurfaceInstance component = raycastHit.collider.GetComponent<GroundSurfaceInstance>();
			TerrainSurface component2 = raycastHit.collider.GetComponent<TerrainSurface>();
			if (component)
			{
				this.contactPoint.surfaceFriction = component.friction;
				this.contactPoint.surfaceType = component.surfaceType;
			}
			else if (component2)
			{
				this.contactPoint.surfaceType = component2.GetDominantSurfaceTypeAtPoint(this.contactPoint.point);
				this.contactPoint.surfaceFriction = component2.GetFriction(this.contactPoint.surfaceType);
			}
			else
			{
				this.contactPoint.surfaceFriction = raycastHit.collider.material.dynamicFriction * 2f;
				this.contactPoint.surfaceType = 0;
			}
			if (this.contactPoint.col.CompareTag("Pop Tire") && this.canPop && this.airLeakTime == -1f && !this.popped)
			{
				this.Deflate();
			}
		}
		else
		{
			this.grounded = false;
			this.contactPoint.distance = this.suspensionParent.suspensionDistance;
			this.contactPoint.point = Vector3.zero;
			this.contactPoint.grounded = false;
			this.contactPoint.normal = this.upDir;
			this.contactPoint.relativeVelocity = Vector3.zero;
			this.contactPoint.col = null;
			this.contactVelocity = Vector3.zero;
			this.contactPoint.surfaceFriction = 0f;
			this.contactPoint.surfaceType = 0;
		}
	}

	// Token: 0x06000671 RID: 1649 RVA: 0x0003729C File Offset: 0x0003549C
	private void GetRawRPM()
	{
		if (this.grounded)
		{
			this.rawRPM = this.contactPoint.relativeVelocity.x / this.circumference * 314.15927f * -this.suspensionParent.flippedSideFactor;
		}
		else
		{
			this.rawRPM = Mathf.Lerp(this.rawRPM, this.actualTargetRPM, (this.actualTorque + this.suspensionParent.brakeForce * this.vp.brakeInput + this.actualEbrake * this.vp.ebrakeInput) * Time.timeScale);
		}
	}

	// Token: 0x06000672 RID: 1650 RVA: 0x00037338 File Offset: 0x00035538
	private void GetSlip()
	{
		if (this.grounded)
		{
			this.sidewaysSlip = this.contactPoint.relativeVelocity.z * 0.1f / this.sidewaysCurveStretch;
			this.forwardSlip = 0.01f * (this.rawRPM - this.currentRPM) / this.forwardCurveStretch;
		}
		else
		{
			this.sidewaysSlip = 0f;
			this.forwardSlip = 0f;
		}
	}

	// Token: 0x06000673 RID: 1651 RVA: 0x000373B0 File Offset: 0x000355B0
	private void ApplyFriction()
	{
		if (this.grounded)
		{
			float f = (this.slipDependence != Wheel.SlipDependenceMode.dependent && this.slipDependence != Wheel.SlipDependenceMode.forward) ? this.forwardSlip : (this.forwardSlip - this.sidewaysSlip);
			float f2 = (this.slipDependence != Wheel.SlipDependenceMode.dependent && this.slipDependence != Wheel.SlipDependenceMode.sideways) ? this.sidewaysSlip : (this.sidewaysSlip - this.forwardSlip);
			float num = Mathf.Clamp01(this.forwardSlipDependence - Mathf.Clamp01(Mathf.Abs(this.sidewaysSlip)));
			float num2 = Mathf.Clamp01(this.sidewaysSlipDependence - Mathf.Clamp01(Mathf.Abs(this.forwardSlip)));
			this.frictionForce = Vector3.Lerp(this.frictionForce, this.tr.TransformDirection(this.forwardFrictionCurve.Evaluate(Mathf.Abs(f)) * (float)(-(float)Math.Sign(this.forwardSlip)) * ((!this.popped) ? this.forwardFriction : this.forwardRimFriction) * num * -this.suspensionParent.flippedSideFactor, 0f, this.sidewaysFrictionCurve.Evaluate(Mathf.Abs(f2)) * (float)(-(float)Math.Sign(this.sidewaysSlip)) * ((!this.popped) ? this.sidewaysFriction : this.sidewaysRimFriction) * num2 * this.normalFrictionCurve.Evaluate(Mathf.Clamp01(Vector3.Dot(this.contactPoint.normal, GlobalControl.worldUpDir))) * ((this.vp.burnout <= 0f || Mathf.Abs(this.targetDrive.rpm) == 0f || this.actualEbrake * this.vp.ebrakeInput != 0f || !this.grounded) ? 1f : ((1f - this.vp.burnout) * (1f - Mathf.Abs(this.vp.accelInput))))) * (0.5f + (1f - this.suspensionParent.compression) * 0.5f * Mathf.Clamp01(Mathf.Abs(this.suspensionParent.tr.InverseTransformDirection(this.localVel).z) * 10f)) * this.contactPoint.surfaceFriction, 1f - this.frictionSmoothness);
			this.rb.AddForceAtPosition(this.frictionForce, this.forceApplicationPoint, ForceMode.Acceleration);
			if (this.contactPoint.col.attachedRigidbody)
			{
				this.contactPoint.col.attachedRigidbody.AddForceAtPosition(-this.frictionForce, this.contactPoint.point, ForceMode.Acceleration);
			}
		}
	}

	// Token: 0x06000674 RID: 1652 RVA: 0x00037688 File Offset: 0x00035888
	private void ApplyDrive()
	{
		float num = 0f;
		float num2 = (!this.suspensionParent.skidSteerBrake) ? this.vp.localVelocity.z : this.vp.localAngularVel.y;
		if (this.vp.brakeIsReverse)
		{
			if (num2 > 0f)
			{
				num = this.suspensionParent.brakeForce * this.vp.brakeInput;
			}
			else if (num2 <= 0f)
			{
				num = this.suspensionParent.brakeForce * Mathf.Clamp01(this.vp.accelInput);
			}
		}
		else
		{
			num = this.suspensionParent.brakeForce * this.vp.brakeInput;
		}
		num += this.axleFriction * 0.1f * (float)((!Mathf.Approximately(this.actualTorque, 0f)) ? 0 : 1);
		if (this.targetDrive.rpm != 0f)
		{
			num *= 1f - this.vp.burnout;
		}
		if (!this.suspensionParent.jammed && this.connected)
		{
			bool flag = ((!Mathf.Approximately(this.actualTorque, 0f) || Mathf.Abs(this.actualTargetRPM) >= 0.01f) && !Mathf.Approximately(this.actualTargetRPM, 0f)) || num + this.actualEbrake * this.vp.ebrakeInput > 0f;
			this.currentRPM = Mathf.Lerp(this.rawRPM, Mathf.Lerp(Mathf.Lerp(this.rawRPM, this.actualTargetRPM, (!flag) ? this.actualTorque : this.EvaluateTorque(this.actualTorque)), 0f, Mathf.Max(num, this.actualEbrake * this.vp.ebrakeInput)), (!flag) ? (this.actualTorque + num + this.actualEbrake * this.vp.ebrakeInput) : this.EvaluateTorque(this.actualTorque + num + this.actualEbrake * this.vp.ebrakeInput));
			this.targetDrive.feedbackRPM = Mathf.Lerp(this.currentRPM, this.rawRPM, this.feedbackRpmBias);
		}
		else
		{
			this.currentRPM = 0f;
			this.targetDrive.feedbackRPM = 0f;
		}
	}

	// Token: 0x06000675 RID: 1653 RVA: 0x00037908 File Offset: 0x00035B08
	private float EvaluateTorque(float t)
	{
		return Mathf.Lerp(this.rpmBiasCurve.Evaluate(t), t, this.rawRPM / (this.rpmBiasCurveLimit * Mathf.Sign(this.actualTargetRPM)));
	}

	// Token: 0x06000676 RID: 1654 RVA: 0x00037944 File Offset: 0x00035B44
	private void PositionWheel()
	{
		if (this.suspensionParent)
		{
			this.rim.position = this.suspensionParent.maxCompressPoint + this.suspensionParent.springDirection * this.suspensionParent.suspensionDistance * ((!Application.isPlaying) ? this.suspensionParent.targetCompression : this.travelDist) + this.suspensionParent.upDir * Mathf.Pow(Mathf.Max(Mathf.Abs(Mathf.Sin(this.suspensionParent.sideAngle * 0.017453292f)), Mathf.Abs(Mathf.Sin(this.suspensionParent.casterAngle * 0.017453292f))), 2f) * this.actualRadius + this.suspensionParent.pivotOffset * this.suspensionParent.tr.TransformDirection(Mathf.Sin(this.tr.localEulerAngles.y * 0.017453292f), 0f, Mathf.Cos(this.tr.localEulerAngles.y * 0.017453292f)) - this.suspensionParent.pivotOffset * ((!Application.isPlaying) ? this.suspensionParent.tr.forward : this.suspensionParent.forwardDir);
		}
		if (!Application.isPlaying || !this.generateHardCollider || this.connected)
		{
		}
	}

	// Token: 0x06000677 RID: 1655 RVA: 0x00037AE8 File Offset: 0x00035CE8
	private void RotateWheel()
	{
		if (this.tr && this.suspensionParent)
		{
			float num = (Mathf.Sign(this.suspensionParent.steerAngle) != this.suspensionParent.flippedSideFactor) ? (1f - this.suspensionParent.ackermannFactor) : (1f + this.suspensionParent.ackermannFactor);
			this.tr.localEulerAngles = new Vector3(this.suspensionParent.camberAngle + this.suspensionParent.casterAngle * this.suspensionParent.steerAngle * this.suspensionParent.flippedSideFactor, -this.suspensionParent.toeAngle * this.suspensionParent.flippedSideFactor + this.suspensionParent.steerDegrees * num, 0f);
		}
		if (Application.isPlaying)
		{
			this.rim.Rotate(Vector3.forward, this.currentRPM * this.suspensionParent.flippedSideFactor * Time.deltaTime);
			if (this.damage > 0f)
			{
				this.rim.localEulerAngles = new Vector3(Mathf.Sin(-this.rim.localEulerAngles.z * 0.017453292f) * Mathf.Clamp(this.damage, 0f, 10f), Mathf.Cos(-this.rim.localEulerAngles.z * 0.017453292f) * Mathf.Clamp(this.damage, 0f, 10f), this.rim.localEulerAngles.z);
			}
			else if (this.rim.localEulerAngles.x != 0f || this.rim.localEulerAngles.y != 0f)
			{
				this.rim.localEulerAngles = new Vector3(0f, 0f, this.rim.localEulerAngles.z);
			}
		}
	}

	// Token: 0x06000678 RID: 1656 RVA: 0x00037D08 File Offset: 0x00035F08
	public void Deflate()
	{
		this.airLeakTime = 0f;
		if (this.impactSnd && this.tireAirClip)
		{
			this.impactSnd.PlayOneShot(this.tireAirClip);
			this.impactSnd.pitch = 1f;
		}
	}

	// Token: 0x06000679 RID: 1657 RVA: 0x00037D61 File Offset: 0x00035F61
	public void FixTire()
	{
		this.popped = false;
		this.tirePressure = this.initialTirePressure;
		this.airLeakTime = -1f;
	}

	// Token: 0x0600067A RID: 1658 RVA: 0x00037D84 File Offset: 0x00035F84
	public void Detach()
	{
		if (this.connected && this.canDetach)
		{
			this.connected = false;
			this.detachedWheel.SetActive(true);
			this.detachedWheel.transform.position = this.rim.position;
			this.detachedWheel.transform.rotation = this.rim.rotation;
			this.detachedCol.sharedMaterial = ((!this.popped) ? this.detachedTireMaterial : this.detachedRimMaterial);
			if (this.tire)
			{
				this.detachedTire.SetActive(!this.popped);
				this.detachedCol.sharedMesh = ((this.airLeakTime < 0f && !this.popped) ? ((!this.tireMeshLoose) ? this.detachTireFilter.sharedMesh : this.tireMeshLoose) : ((!this.rimMeshLoose) ? this.detachFilter.sharedMesh : this.rimMeshLoose));
			}
			else
			{
				this.detachedCol.sharedMesh = ((!this.rimMeshLoose) ? this.detachFilter.sharedMesh : this.rimMeshLoose);
			}
			this.rb.mass -= this.mass;
			this.detachedBody.velocity = this.rb.GetPointVelocity(this.rim.position);
			this.detachedBody.angularVelocity = this.rb.angularVelocity;
			this.rim.gameObject.SetActive(false);
			if (this.sphereColTr)
			{
				this.sphereColTr.gameObject.SetActive(false);
			}
		}
	}

	// Token: 0x0600067B RID: 1659 RVA: 0x00037F6C File Offset: 0x0003616C
	public void GetWheelDimensions(float radiusMargin, float widthMargin)
	{
		Mesh mesh = null;
		Mesh mesh2 = null;
		Transform transform = base.transform;
		if (base.transform.childCount > 0)
		{
			if (base.transform.GetChild(0).GetComponent<MeshFilter>())
			{
				mesh = base.transform.GetChild(0).GetComponent<MeshFilter>().sharedMesh;
				transform = base.transform.GetChild(0);
			}
			if (base.transform.GetChild(0).childCount > 0 && base.transform.GetChild(0).GetChild(0).GetComponent<MeshFilter>())
			{
				mesh2 = base.transform.GetChild(0).GetChild(0).GetComponent<MeshFilter>().sharedMesh;
			}
			Mesh mesh3 = (!mesh2) ? mesh : mesh2;
			if (mesh3)
			{
				float num = 0f;
				float num2 = 0f;
				foreach (Vector3 vector in mesh3.vertices)
				{
					Vector2 vector2 = new Vector2(vector.x * transform.localScale.x, vector.y * transform.localScale.y);
					if (vector2.magnitude > num2)
					{
						Vector2 vector3 = new Vector2(vector.x * transform.localScale.x, vector.y * transform.localScale.y);
						num2 = vector3.magnitude;
					}
					if (Mathf.Abs(vector.z * transform.localScale.z) > num)
					{
						num = Mathf.Abs(vector.z * transform.localScale.z);
					}
				}
				this.tireRadius = num2 + radiusMargin;
				this.tireWidth = num + widthMargin;
				if (mesh2 && mesh)
				{
					num = 0f;
					num2 = 0f;
					foreach (Vector3 vector4 in mesh.vertices)
					{
						Vector2 vector5 = new Vector2(vector4.x * transform.localScale.x, vector4.y * transform.localScale.y);
						if (vector5.magnitude > num2)
						{
							Vector2 vector6 = new Vector2(vector4.x * transform.localScale.x, vector4.y * transform.localScale.y);
							num2 = vector6.magnitude;
						}
						if (Mathf.Abs(vector4.z * transform.localScale.z) > num)
						{
							num = Mathf.Abs(vector4.z * transform.localScale.z);
						}
					}
					this.rimRadius = num2 + radiusMargin;
					this.rimWidth = num + widthMargin;
				}
				else
				{
					this.rimRadius = num2 * 0.5f + radiusMargin;
					this.rimWidth = num * 0.5f + widthMargin;
				}
			}
			else
			{
				Debug.LogError("No rim or tire meshes found for getting wheel dimensions.", this);
			}
		}
	}

	// Token: 0x0600067C RID: 1660 RVA: 0x000382BC File Offset: 0x000364BC
	public void Reattach()
	{
		if (!this.connected)
		{
			this.connected = true;
			this.detachedWheel.SetActive(false);
			this.rb.mass += this.mass;
			this.rim.gameObject.SetActive(true);
			if (this.sphereColTr)
			{
				this.sphereColTr.gameObject.SetActive(true);
			}
		}
	}

	// Token: 0x0600067D RID: 1661 RVA: 0x00038334 File Offset: 0x00036534
	private void OnDrawGizmosSelected()
	{
		this.tr = base.transform;
		if (this.tr.childCount > 0)
		{
			this.rim = this.tr.GetChild(0);
			if (this.rim.childCount > 0)
			{
				this.tire = this.rim.GetChild(0);
			}
		}
		float radius = Mathf.Lerp(this.rimRadius, this.tireRadius, this.tirePressure);
		if (this.tirePressure < 1f && this.tirePressure > 0f)
		{
			Gizmos.color = new Color(1f, 1f, 0f, (!this.popped) ? 1f : 0.5f);
			GizmosExtra.DrawWireCylinder(this.rim.position, this.rim.forward, radius, this.tireWidth * 2f);
		}
		Gizmos.color = Color.white;
		GizmosExtra.DrawWireCylinder(this.rim.position, this.rim.forward, this.tireRadius, this.tireWidth * 2f);
		Gizmos.color = ((this.tirePressure != 0f && !this.popped) ? Color.cyan : Color.green);
		GizmosExtra.DrawWireCylinder(this.rim.position, this.rim.forward, this.rimRadius, this.rimWidth * 2f);
		Gizmos.color = new Color(1f, 1f, 1f, (this.tirePressure >= 1f) ? 1f : 0.5f);
		GizmosExtra.DrawWireCylinder(this.rim.position, this.rim.forward, this.tireRadius, this.tireWidth * 2f);
		Gizmos.color = ((this.tirePressure != 0f && !this.popped) ? Color.cyan : Color.green);
		GizmosExtra.DrawWireCylinder(this.rim.position, this.rim.forward, this.rimRadius, this.rimWidth * 2f);
	}

	// Token: 0x0600067E RID: 1662 RVA: 0x0003857A File Offset: 0x0003677A
	private void OnDestroy()
	{
		if (Application.isPlaying && this.detachedWheel)
		{
			UnityEngine.Object.Destroy(this.detachedWheel);
		}
	}

	// Token: 0x04000A30 RID: 2608
	[NonSerialized]
	public Transform tr;

	// Token: 0x04000A31 RID: 2609
	private Rigidbody rb;

	// Token: 0x04000A32 RID: 2610
	[NonSerialized]
	public VehicleParent vp;

	// Token: 0x04000A33 RID: 2611
	[NonSerialized]
	public Suspension suspensionParent;

	// Token: 0x04000A34 RID: 2612
	[NonSerialized]
	public Transform rim;

	// Token: 0x04000A35 RID: 2613
	private Transform tire;

	// Token: 0x04000A36 RID: 2614
	private Vector3 localVel;

	// Token: 0x04000A37 RID: 2615
	[Tooltip("Generate a sphere collider to represent the wheel for side collisions")]
	public bool generateHardCollider = true;

	// Token: 0x04000A38 RID: 2616
	private SphereCollider sphereCol;

	// Token: 0x04000A39 RID: 2617
	private Transform sphereColTr;

	// Token: 0x04000A3A RID: 2618
	[Tooltip("Bias for feedback RPM lerp between target RPM and raw RPM")]
	[Range(0f, 1f)]
	[Header("Rotation")]
	public float feedbackRpmBias;

	// Token: 0x04000A3B RID: 2619
	[Tooltip("Curve for setting final RPM of wheel based on driving torque/brake force, x-axis = torque/brake force, y-axis = lerp between raw RPM and target RPM")]
	public AnimationCurve rpmBiasCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);

	// Token: 0x04000A3C RID: 2620
	[Tooltip("As the RPM of the wheel approaches this value, the RPM bias curve is interpolated with the default linear curve")]
	public float rpmBiasCurveLimit = float.PositiveInfinity;

	// Token: 0x04000A3D RID: 2621
	[Range(0f, 10f)]
	public float axleFriction;

	// Token: 0x04000A3E RID: 2622
	[Range(0f, 1f)]
	[Header("Friction")]
	public float frictionSmoothness = 0.5f;

	// Token: 0x04000A3F RID: 2623
	public float forwardFriction = 1f;

	// Token: 0x04000A40 RID: 2624
	public float sidewaysFriction = 1f;

	// Token: 0x04000A41 RID: 2625
	public float forwardRimFriction = 0.5f;

	// Token: 0x04000A42 RID: 2626
	public float sidewaysRimFriction = 0.5f;

	// Token: 0x04000A43 RID: 2627
	public float forwardCurveStretch = 1f;

	// Token: 0x04000A44 RID: 2628
	public float sidewaysCurveStretch = 1f;

	// Token: 0x04000A45 RID: 2629
	private Vector3 frictionForce = Vector3.zero;

	// Token: 0x04000A46 RID: 2630
	[Tooltip("X-axis = slip, y-axis = friction")]
	public AnimationCurve forwardFrictionCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);

	// Token: 0x04000A47 RID: 2631
	[Tooltip("X-axis = slip, y-axis = friction")]
	public AnimationCurve sidewaysFrictionCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);

	// Token: 0x04000A48 RID: 2632
	[NonSerialized]
	public float forwardSlip;

	// Token: 0x04000A49 RID: 2633
	[NonSerialized]
	public float sidewaysSlip;

	// Token: 0x04000A4A RID: 2634
	public Wheel.SlipDependenceMode slipDependence = Wheel.SlipDependenceMode.sideways;

	// Token: 0x04000A4B RID: 2635
	[Range(0f, 2f)]
	public float forwardSlipDependence = 2f;

	// Token: 0x04000A4C RID: 2636
	[Range(0f, 2f)]
	public float sidewaysSlipDependence = 2f;

	// Token: 0x04000A4D RID: 2637
	[Tooltip("Adjusts how much friction the wheel has based on the normal of the ground surface. X-axis = normal dot product, y-axis = friction multiplier")]
	public AnimationCurve normalFrictionCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);

	// Token: 0x04000A4E RID: 2638
	[Header("Size")]
	public float tireRadius;

	// Token: 0x04000A4F RID: 2639
	public float rimRadius;

	// Token: 0x04000A50 RID: 2640
	public float tireWidth;

	// Token: 0x04000A51 RID: 2641
	public float rimWidth;

	// Token: 0x04000A52 RID: 2642
	[NonSerialized]
	public float setTireWidth;

	// Token: 0x04000A53 RID: 2643
	[NonSerialized]
	public float tireWidthPrev;

	// Token: 0x04000A54 RID: 2644
	[NonSerialized]
	public float setTireRadius;

	// Token: 0x04000A55 RID: 2645
	[NonSerialized]
	public float tireRadiusPrev;

	// Token: 0x04000A56 RID: 2646
	[NonSerialized]
	public float setRimWidth;

	// Token: 0x04000A57 RID: 2647
	[NonSerialized]
	public float rimWidthPrev;

	// Token: 0x04000A58 RID: 2648
	[NonSerialized]
	public float setRimRadius;

	// Token: 0x04000A59 RID: 2649
	[NonSerialized]
	public float rimRadiusPrev;

	// Token: 0x04000A5A RID: 2650
	[NonSerialized]
	public float actualRadius;

	// Token: 0x04000A5B RID: 2651
	[Header("Tire")]
	[Range(0f, 1f)]
	public float tirePressure = 1f;

	// Token: 0x04000A5C RID: 2652
	[NonSerialized]
	public float setTirePressure;

	// Token: 0x04000A5D RID: 2653
	[NonSerialized]
	public float tirePressurePrev;

	// Token: 0x04000A5E RID: 2654
	private float initialTirePressure;

	// Token: 0x04000A5F RID: 2655
	public bool popped;

	// Token: 0x04000A60 RID: 2656
	[NonSerialized]
	public bool setPopped;

	// Token: 0x04000A61 RID: 2657
	[NonSerialized]
	public bool poppedPrev;

	// Token: 0x04000A62 RID: 2658
	public bool canPop;

	// Token: 0x04000A63 RID: 2659
	[Tooltip("Requires deform shader")]
	public float deformAmount;

	// Token: 0x04000A64 RID: 2660
	private Material rimMat;

	// Token: 0x04000A65 RID: 2661
	private Material tireMat;

	// Token: 0x04000A66 RID: 2662
	private float airLeakTime = -1f;

	// Token: 0x04000A67 RID: 2663
	[Range(0f, 1f)]
	public float rimGlow;

	// Token: 0x04000A68 RID: 2664
	private float glowAmount;

	// Token: 0x04000A69 RID: 2665
	private Color glowColor;

	// Token: 0x04000A6A RID: 2666
	[NonSerialized]
	public bool updatedSize;

	// Token: 0x04000A6B RID: 2667
	[NonSerialized]
	public bool updatedPopped;

	// Token: 0x04000A6C RID: 2668
	private float currentRPM;

	// Token: 0x04000A6D RID: 2669
	[NonSerialized]
	public DriveForce targetDrive;

	// Token: 0x04000A6E RID: 2670
	[NonSerialized]
	public float rawRPM;

	// Token: 0x04000A6F RID: 2671
	[NonSerialized]
	public WheelContact contactPoint = new WheelContact();

	// Token: 0x04000A70 RID: 2672
	[NonSerialized]
	public bool getContact = true;

	// Token: 0x04000A71 RID: 2673
	[NonSerialized]
	public bool grounded;

	// Token: 0x04000A72 RID: 2674
	private float airTime;

	// Token: 0x04000A73 RID: 2675
	[NonSerialized]
	public float travelDist;

	// Token: 0x04000A74 RID: 2676
	private Vector3 upDir;

	// Token: 0x04000A75 RID: 2677
	private float circumference;

	// Token: 0x04000A76 RID: 2678
	[NonSerialized]
	public Vector3 contactVelocity;

	// Token: 0x04000A77 RID: 2679
	private float actualEbrake;

	// Token: 0x04000A78 RID: 2680
	private float actualTargetRPM;

	// Token: 0x04000A79 RID: 2681
	private float actualTorque;

	// Token: 0x04000A7A RID: 2682
	[NonSerialized]
	public Vector3 forceApplicationPoint;

	// Token: 0x04000A7B RID: 2683
	[Tooltip("Apply friction forces at ground point")]
	public bool applyForceAtGroundContact;

	// Token: 0x04000A7C RID: 2684
	[Header("Audio")]
	public AudioSource impactSnd;

	// Token: 0x04000A7D RID: 2685
	public AudioClip[] tireHitClips;

	// Token: 0x04000A7E RID: 2686
	public AudioClip rimHitClip;

	// Token: 0x04000A7F RID: 2687
	public AudioClip tireAirClip;

	// Token: 0x04000A80 RID: 2688
	public AudioClip tirePopClip;

	// Token: 0x04000A81 RID: 2689
	[Header("Damage")]
	public float detachForce = float.PositiveInfinity;

	// Token: 0x04000A82 RID: 2690
	[NonSerialized]
	public float damage;

	// Token: 0x04000A83 RID: 2691
	public float mass = 0.05f;

	// Token: 0x04000A84 RID: 2692
	[NonSerialized]
	public bool canDetach;

	// Token: 0x04000A85 RID: 2693
	[NonSerialized]
	public bool connected = true;

	// Token: 0x04000A86 RID: 2694
	public Mesh tireMeshLoose;

	// Token: 0x04000A87 RID: 2695
	public Mesh rimMeshLoose;

	// Token: 0x04000A88 RID: 2696
	private GameObject detachedWheel;

	// Token: 0x04000A89 RID: 2697
	private GameObject detachedTire;

	// Token: 0x04000A8A RID: 2698
	private MeshCollider detachedCol;

	// Token: 0x04000A8B RID: 2699
	private Rigidbody detachedBody;

	// Token: 0x04000A8C RID: 2700
	private MeshFilter detachFilter;

	// Token: 0x04000A8D RID: 2701
	private MeshFilter detachTireFilter;

	// Token: 0x04000A8E RID: 2702
	public PhysicMaterial detachedTireMaterial;

	// Token: 0x04000A8F RID: 2703
	public PhysicMaterial detachedRimMaterial;

	// Token: 0x02000161 RID: 353
	public enum SlipDependenceMode
	{
		// Token: 0x04000A91 RID: 2705
		dependent,
		// Token: 0x04000A92 RID: 2706
		forward,
		// Token: 0x04000A93 RID: 2707
		sideways,
		// Token: 0x04000A94 RID: 2708
		independent
	}
}
